/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 * \file     Port_Ip.c                                                                                  *
 * \brief    AUTOSAR 4.3.1 MCAL Port Driver                                                              *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2023/07/14     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
#include "RegHelper.h"
#include "Port_Ip.h"
#include "Port_Fault.h"
/********************************************************************************************************
 *                                 Private Macro definition                                             *
 *******************************************************************************************************/
/* Spell pin and mux into one field*/
#define PINCTRL_IS_IDX(pin, mux)   (((pin) << 8) + (mux))

/* check last ret, if ret is OK, execute function, otherwise do nothing*/
#define CALL_RET_CHECK(ret, funcall) \
    if (E_OK == (ret)) { (ret) = (funcall); }


#define PORT_START_SEC_CODE
#include "Port_MemMap.h"
/********************************************************************************************************
 *                               Private Inline Function Declarations                                    *
 *******************************************************************************************************/

/** *****************************************************************************************************
 * Syntax             : static inline uint32 Port_Ip_PinReg(uint32 base, uint32 offset, uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - pin register base address
 *                      offset - pin register offset
 *                      pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : port pin address
 *
 * Description        : Calculate the register address of the pin
 *******************************************************************************************************/
static inline uint32 Port_Ip_PinReg(uint32 base, uint32 offset, uint32 pin)
{
    return base + offset + (pin * 4U);
}
/** *****************************************************************************************************
 * Syntax             : static inline void
 *                      Port_Ip_WritePinReg(uint32 base, uint32 offset, uint32 pin, uint32 val)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - pin register base address
 *                      offset - pin register offset
 *                      pin - pin index
 *                      val - value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : Write value to the register address of the pin
 *******************************************************************************************************/
static inline void Port_Ip_WritePinReg(uint32 base, uint32 offset, uint32 pin, uint32 val)
{
    writel(val, Port_Ip_PinReg(base, offset, pin));
}
/** *****************************************************************************************************
 * Syntax             : static inline uint32 Port_Ip_ReadPinReg(uint32 base, uint32 offset, uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - pin register base address
 *                      offset - pin register offset
 *                      pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : value of pin register
 *
 * Description        : Read value from the register address of the pin
 *******************************************************************************************************/
static inline uint32 Port_Ip_ReadPinReg(uint32 base, uint32 offset, uint32 pin)
{
    return readl(Port_Ip_PinReg(base, offset, pin));
}
/** *****************************************************************************************************
 * Syntax             : static inline void Port_Ip_ModifyPinReg(uint32 base, uint32 offset, uint32 pin,
 *                                 uint32 bit, uint32 width, uint32 val)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - pin register base address
 *                      offset - pin register offset
 *                      pin - pin index
 *                      bit - BIT to modify
 *                      width - width to modify
 *                      val - value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : modify value of the register address of the pin
 *******************************************************************************************************/
static inline void Port_Ip_ModifyPinReg(uint32 base, uint32 offset, uint32 pin,
                                        uint32 bit, uint32 width, uint32 val)
{
    uint32 v = Port_Ip_ReadPinReg(base, offset, pin);
    v &= ~(BIT_MASK(width) << bit);
    v |= (val & BIT_MASK(width)) << bit;
    Port_Ip_WritePinReg(base, offset, pin, v);
}

/** *****************************************************************************************************
 * Syntax             : static inline uint8 Port_Ip_SetOpenDrain(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device base
 *                      pin - controller pin index
 *                      value - open drain/push pull to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set open drain/push pull for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static inline uint8 Port_Ip_SetOpenDrain(uint32 base, uint32 pin, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    /* The controller must have MUX function. */
    if ((((uint32)PORT_PIN_OPEN_DRAIN !=  value) &&  ((uint32)PORT_PIN_PUSH_PULL != value)))
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 set open drain/push pull*/
        Port_Ip_ModifyPinReg(base, PORT_MUX_CONFIG_REG_OFFSET, pin, MUX_ODE_SHIFT, MUX_ODE_WIDTH,
                             value);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static inline uint8 Port_Ip_SetPull(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device base
 *                      pin - controller pin index
 *                      value - pulls to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set pulls mode for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static inline uint8 Port_Ip_SetPull(uint32 base, uint32 pin, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (value > (uint32)PORT_PIN_PULL_UP)
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 set pulls mode*/
        Port_Ip_ModifyPinReg(base, PORT_PAD_CONFIG_REG_OFFSET, pin, PAD_PULL_SHIFT, PAD_PULL_WIDTH,
                             value);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static inline uint8 Port_Ip_SetDriveStrength(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device base
 *                      pin - controller pin index
 *                      value - drive strength to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set drive strength for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static inline uint8 Port_Ip_SetDriveStrength(uint32 base, uint32 pin, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (value > (uint32)PORT_PIN_DS_12MA)
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 set drive strength*/
        Port_Ip_ModifyPinReg(base, PORT_PAD_CONFIG_REG_OFFSET, pin, PAD_DS_SHIFT, PAD_DS_WIDTH, value);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static inline uint8 Port_Ip_SetInputSchmitt(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device base
 *                      pin - controller pin index
 *                      value - schmitt mode to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set schmitt mode for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static inline uint8 Port_Ip_SetInputSchmitt(uint32 base, uint32 pin,
        uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if ((((uint32)PORT_PIN_IS_CMOS_SCHMITT != value) && ((uint32)PORT_PIN_IS_CMOS != value)))
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 set schmitt mode*/
        Port_Ip_ModifyPinReg(base, PORT_PAD_CONFIG_REG_OFFSET, pin, PAD_IS_SHIFT, PAD_IS_WIDTH, value);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static inline uint8 Port_Ip_SetSlewRate(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device base
 *                      pin - controller pin index
 *                      value - slew rate to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set slew rate for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static inline uint8 Port_Ip_SetSlewRate(uint32 base, uint32 pin, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if ((((uint32)PORT_PIN_SR_FAST != value) && ((uint32)PORT_PIN_SR_SLOW != value)))
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 set slew rate*/
        Port_Ip_ModifyPinReg(base, PORT_PAD_CONFIG_REG_OFFSET, pin, PAD_SR_SHIFT, PAD_SR_WIDTH, value);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static inline uint8 Port_Ip_SetModeSelect(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device base
 *                      pin - controller pin index
 *                      value - mode select to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set mode select for the pin, for analog pin only
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static inline uint8 Port_Ip_SetModeSelect(uint32 base, uint32 pin, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (((uint32)PORT_PIN_SETTING_ANALOG_3V3 != value) && ((uint32)PORT_PIN_SETTING_ANALOG_5V != value))
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 set mode select for analog pin*/
        Port_Ip_ModifyPinReg(base, PORT_PAD_CONFIG_REG_OFFSET, pin, PAD_MS_SHIFT, PAD_MS_WIDTH, value);
    }

    return ret;
}
/********************************************************************************************************
 *                                  Private Function Declarations                                       *
 *******************************************************************************************************/
/** *****************************************************************************************************
 * Syntax             : static boolean Port_Ip_IsAnalogPin(uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE/FALSE
 *
 * Description        : check if is Analog Pin
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static boolean Port_Ip_IsAnalogPin(uint32 pin)
{
    boolean IsAnalogPin = FALSE;
    /*set bit20 to 0 when GPIO LA/K/U/A/B/C used as digital,
    if use default 1, will cause a partial voltage on the pin and deviate from the actual voltage*/
#if (defined(E3650))
    if ((pin <= GPIO_C15) || ((pin >= GPIO_LA0) && (pin <= GPIO_LA31)))
#endif
    {
        IsAnalogPin = TRUE;
    } /* else is not needed*/

    return IsAnalogPin;
}

/** *****************************************************************************************************
 * Syntax             : static Port_PinMapType *Port_Ip_PinGetMatch(Port_PinMapType *listPtr,
                                uint32 size, uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : listPtr - maplist
 *                      size - mapsize
 *                      pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : the match item in maplist
 *
 * Description        : Match pinctrl in map
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static const Port_PinMapType *Port_Ip_PinGetMatch(const Port_PinMapType *listPtr,
        uint32 size, uint32 pin)
{
    const Port_PinMapType *matchPtr = listPtr;
    uint32 i;

    if (NULL_PTR != matchPtr)
    {
        for (i = 0U; i < size; i++)
        {
            if ((pin >= matchPtr->pinStart) && (pin < (matchPtr->pinStart + matchPtr->pinNum)))
            {
                break;
            }

            matchPtr++;
        }

        if (i == size)
        {
            matchPtr = NULL_PTR;
        }
    }

    return matchPtr;
}

/** *****************************************************************************************************
 * Syntax             : static uint32 Port_Ip_PinGetBase(Port_PinMapType *listPtr, uint32 size, uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : listPtr - maplist
 *                      size - mapsize
 *                      pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : the base of the match item in maplist
 *
 * Description        : get the base of pinctrl in map
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static uint32 Port_Ip_PinGetBase(const Port_PinMapType *listPtr, uint32 size, uint32 pin)
{
    const Port_PinMapType *matchPtr;
    uint32 base = UINT32_MAX;

    matchPtr = Port_Ip_PinGetMatch(listPtr, size, pin);

    if (NULL_PTR != matchPtr)
    {
        base = matchPtr->ctrlBase;
    }

    return base;
}

/** *****************************************************************************************************
 * Syntax             : static uint32 Port_Ip_PinGetIndex(Port_PinMapType *listPtr, uint32 size, uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : listPtr - maplist
 *                      size - mapsize
 *                      pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : the localpin index
 *
 * Description        : get the local pin index of pinctrl in map
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static uint32 Port_Ip_PinGetIndex(const Port_PinMapType *listPtr, uint32 size, uint32 pin)
{
    const Port_PinMapType *matchPtr;
    uint32 index = UINT32_MAX;

    matchPtr = Port_Ip_PinGetMatch(listPtr, size, pin);

    if (NULL_PTR != matchPtr)
    {
        index = (pin - matchPtr->pinStart + matchPtr->ctrlIdx);
    }

    return index;
}

/** *****************************************************************************************************
 * Syntax             : static uint32 Port_Ip_PinctrlGetBase(uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : the pinctrl base
 *
 * Description        : get the pinctrl base
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static uint32 Port_Ip_PinctrlGetBase(uint32 pin)
{
    return Port_Ip_PinGetBase(&Port_PinctrlMaps[0],
                              sizeof(Port_PinctrlMaps) / sizeof(Port_PinctrlMaps[0]), pin);
}

/** *****************************************************************************************************
 * Syntax             : static uint32 Port_Ip_PinctrlGetLocalPin(uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : the pinctrl local pin index
 *
 * Description        : get the pinctrl local pin index
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static uint32 Port_Ip_PinctrlGetLocalPin(uint32 pin)
{
    return Port_Ip_PinGetIndex(&Port_PinctrlMaps[0],
                               sizeof(Port_PinctrlMaps) / sizeof(Port_PinctrlMaps[0]), pin);
}

/** *****************************************************************************************************
 * Syntax             : static uint32 Port_Ip_GpioGetBase(uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : the gpio base
 *
 * Description        : get the gpio base
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static uint32 Port_Ip_GpioGetBase(uint32 pin)
{
    return Port_Ip_PinGetBase(&Port_GpioMaps[0], sizeof(Port_GpioMaps) / sizeof(Port_GpioMaps[0]), pin);
}

/** *****************************************************************************************************
 * Syntax             : static uint32 Port_Ip_GpioGetIndex(uint32 pin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : the gpio index
 *
 * Description        : get the gpio index
 * Traceability       : SWSR_PORT_003
 *******************************************************************************************************/
static uint32 Port_Ip_GpioGetIndex(uint32 pin)
{
    return Port_Ip_PinGetIndex(&Port_GpioMaps[0], sizeof(Port_GpioMaps) / sizeof(Port_GpioMaps[0]),
                               pin);
}
/** *****************************************************************************************************
 * Syntax             : static void Port_Ip_SetInputSelectReg(uint32 pin, uint32 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - pin index to search input select
 *                      mux - pin mux to search input select
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : set the input select for input pin and mux
 * Traceability       : SWSR_PORT_004
 *******************************************************************************************************/
static void Port_Ip_SetInputSelectReg(uint32 pin, uint32 mux)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint32 left = 0U;
    uint32 right = (PORT_INPUT_SELECT_NUM - 1U);
    uint32 mid;
    const Port_InputSelectType *selectPtr;
    boolean flag = FALSE;
#if defined(PORT_XTRGOI_PIN_ENABLE)
    uint8 isXtrgPin = 0U;
    Port_XtrgOutputConfigType xtrgOutput;
#endif

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Using the dichotomy lookup table,
            the table need to be arranged in pin-mux order from smallest to largest*/
    while (left <= right)
    {
        mid = (left + right) / 2U;
        selectPtr = &Port_PinctrlIs[mid];

        /* #40 The corresponding item is found*/
        if (PINCTRL_IS_IDX(selectPtr->pin, selectPtr->mux) == PINCTRL_IS_IDX(pin, mux))
        {
#if defined(PORT_XTRGOI_PIN_ENABLE)
#if NUM_OF_XTRG1_OUTPUT_PINS != 0
            uint32 index_xtrg1 = 0U;
            /* #401 xtrgoi used as input, set inputselect, used as output, can not set inputselect */
            while (index_xtrg1 < NUM_OF_XTRG1_OUTPUT_PINS)
            {
                xtrgOutput = Port_PinXtrg1_OutputConfig[index_xtrg1];

                if (PINCTRL_IS_IDX(xtrgOutput.pinIndex, xtrgOutput.mux) == PINCTRL_IS_IDX(pin, mux))
                {
                    isXtrgPin = 1U;
                    break;
                }/* else not needed */

                index_xtrg1++;
            }
#endif
#if NUM_OF_XTRG2_OUTPUT_PINS != 0
            uint32 index_xtrg2 = 0U;
            while (index_xtrg2 < NUM_OF_XTRG2_OUTPUT_PINS)
            {
                xtrgOutput = Port_PinXtrg2_OutputConfig[index_xtrg2];

                if (PINCTRL_IS_IDX(xtrgOutput.pinIndex, xtrgOutput.mux) == PINCTRL_IS_IDX(pin, mux))
                {
                    isXtrgPin = 1U;
                    break;
                }/* else not needed */

                index_xtrg2++;
            }
#endif
            /* Xtrgoi used as output, can not set inputselect */
            if (0U == isXtrgPin)
            {
                writel(selectPtr->value, selectPtr->base + selectPtr->offset);
            }
#else
            writel(selectPtr->value, selectPtr->base + selectPtr->offset);
#endif
            flag = TRUE;
            /* #20 Need to look in the first half*/
        }
        else if (PINCTRL_IS_IDX(selectPtr->pin, selectPtr->mux) > PINCTRL_IS_IDX(pin, mux))
        {
            if (0U == mid)
            {
                flag = TRUE;
            }
            else
            {
                right = mid - 1U;
            }

            /* #30 Need to look in the back half*/
        }
        else
        {
            left = mid + 1U;
        }

        if (TRUE == flag)
        {
            break;
        } /** else not needed*/
    }
}
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_SetFunction(uint32 base, uint32 pin, uint32 value,
                                 uint32 socPin)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device base
 *                      pin - controller pin index
 *                      value - mux to set
 *                      socPin - soc pin index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set mux for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_004 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_SetFunction(uint32 base, uint32 pin, uint32 value,
                                 uint32 socPin)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    /* The controller must have MUX function. */
    if (value > (uint32)PORT_PIN_MUX_ALT9)
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 set input select*/
        Port_Ip_SetInputSelectReg(socPin, value);
        /* #30 set pin mux*/
        Port_Ip_ModifyPinReg(base, PORT_MUX_CONFIG_REG_OFFSET, pin, MUX_FUNC_SHIFT, MUX_FUNC_WIDTH,
                             value);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_SetForceInput(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device abse
 *                      pin - controller pin index
 *                      value - force input to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set force input for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_SetForceInput(uint32 base, uint32 pin, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;
    uint32 finIp = 0;
    uint32 fin;
    uint32 fv;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (value > (uint32)PORT_PIN_FORCE_INPUT_GPIO_READBACK)
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 Converts to register corresponding value*/
        if (value <= (uint32)PORT_PIN_FORCE_INPUT_ENABLE)
        {
            fin = value;
            fv = PAD_FORCE_INPUT_VALUE_0;
            finIp = PAD_INPUT_IP_NO_MUX_FORCE;
        }
        else if ((uint32)PORT_PIN_FORCE_INPUT_GPIO_READBACK == value)
        {
            fin = PAD_INPUT_FORCE_ENABLE;
            fv = PAD_FORCE_INPUT_VALUE_0;
            finIp |= PAD_INPUT_IP_MUX0_FORCE_ENABLE;
        }
        else
        {
            fin = PAD_INPUT_FORCE_DISABLE;
            finIp = PAD_INPUT_IP_NO_MUX_FORCE;

            if (value == (uint32)PORT_PIN_FORCE_INPUT_HIGH)
            {
                fv = PAD_FORCE_INPUT_VALUE_1;
            }
            else
            {
                fv = PAD_FORCE_INPUT_VALUE_0;
            }
        }

        /* #30 set force input, include fin and fv*/
        Port_Ip_ModifyPinReg(base, PORT_MUX_CONFIG_REG_OFFSET, pin, MUX_FIN_IP_SHIFT, MUX_FIN_IP_WIDTH, finIp);
        Port_Ip_ModifyPinReg(base, PORT_MUX_CONFIG_REG_OFFSET, pin, MUX_FIN_SHIFT, MUX_FIN_WIDTH, fin);
        Port_Ip_ModifyPinReg(base, PORT_MUX_CONFIG_REG_OFFSET, pin, MUX_FV_SHIFT, MUX_FV_WIDTH, fv);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_SetForceOutput(uint32 base, uint32 pin, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port device abse
 *                      pin - controller pin index
 *                      value - force output to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : set force output for the pin
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_SetForceOutput(uint32 base, uint32 pin, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret = E_OK;
    uint32 en;
    uint32 fv;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (value > (uint32)PORT_PIN_FORCE_OUTPUT_LOW)
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 Converts to register corresponding value*/
        if (value == (uint32)PORT_PIN_FORCE_OUTPUT_DISABLE)
        {
            en = PAD_OUTPUT_FORCE_DISABLE;
            fv = PAD_FORCE_OUTPUT_VALUE_0;
        }
        else
        {
            en = PAD_OUTPUT_FORCE_ENABLE;

            if (value == (uint32)PORT_PIN_FORCE_OUTPUT_HIGH)
            {
                fv = PAD_FORCE_OUTPUT_VALUE_1;
            }
            else
            {
                fv = PAD_FORCE_OUTPUT_VALUE_0;
            }
        }

        /* #30 set force output, include en and fv*/
        Port_Ip_ModifyPinReg(base, PORT_MUX_CONFIG_REG_OFFSET, pin, MUX_DO_FORCE_EN_SHIFT, MUX_DO_FORCE_EN_WIDTH, en);
        Port_Ip_ModifyPinReg(base, PORT_MUX_CONFIG_REG_OFFSET, pin, MUX_DO_FORCE_VALUE_SHIFT, MUX_DO_FORCE_VALUE_WIDTH, fv);
    }

    return ret;
}
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_ConfigFun(uint32 base, uint32 socPin, uint32 localpin,
                               Port_PinConfigType config, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - port pin controller base
 *                      socPin - soc pin index
 *                      localPin - controller pin index
 *                      config - config type
 *                      value - value to set
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : Configure pin parameters. Note that the pin index is controller local index.
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055 SWSR_PORT_056
 *                      SWSR_PORT_006 SWSR_PORT_004 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_ConfigFun(uint32 base, uint32 socPin, uint32 localpin,
                               Port_PinConfigType config, uint32 value)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint8 ret;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (socPin >= PORT_PIN_NUM)
    {
        ret = PORT_E_PARAM_PIN;
    }
    else
    {
        switch (config)
        {
        case PORT_CONFIG_FUNCTION:
            /* #30 set pin mux*/
            ret = Port_Ip_SetFunction(base, localpin, value, socPin);
            break;

        case PORT_CONFIG_DRIVE:
            /* #40 set Open drain or push pull*/
            ret = Port_Ip_SetOpenDrain(base, localpin, value);
            break;

        case PORT_CONFIG_PULL:
            /* #50 set pulls mode*/
            ret = Port_Ip_SetPull(base, localpin, value);
            break;

        case PORT_CONFIG_DRIVE_STRENGTH:
            /* #60 set pulls mode*/
            ret = Port_Ip_SetDriveStrength(base, localpin, value);
            break;

        case PORT_CONFIG_INPUT_SCHMITT:
            /* #70 set schmitt mode*/
            ret = Port_Ip_SetInputSchmitt(base, localpin, value);
            break;

        case PORT_CONFIG_SLEW_RATE:
            /* #80 set slew rate*/
            ret = Port_Ip_SetSlewRate(base, localpin, value);
            break;

        case PORT_CONFIG_FORCE_INPUT:
            /* #90 set force input*/
            ret = Port_Ip_SetForceInput(base, localpin, value);
            break;

        case PORT_CONFIG_FORCE_OUTPUT:
            /* #100 set force output*/
            ret = Port_Ip_SetForceOutput(base, localpin, value);
            break;

        case PORT_CONFIG_MODE_SELECT:
            /* #110 set mode select for analog pin*/
            ret = Port_Ip_SetModeSelect(base, localpin, value);
            break;

        default:
            ret = PORT_E_CONFIG_TYPE;
            break;
        }
    }

    return ret;
}

/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_Config(uint32 base, uint32 pin,
                                   Port_PinConfigType config, uint32 value)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : base - pinctrl device base
 *                      pin - SOC pin index
 *                      config - Configuration options type
 *                      value - Configuration value, depending on config type.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : Configure each properties of the PIN.
 * Traceability       : SWSR_PORT_003 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_Config(uint32 base, uint32 pin,
                            Port_PinConfigType config, uint32 value)
{
    uint8 ret = PORT_E_PARAM_PIN;
    uint32 localPin;

    if (UINT32_MAX != base)
    {
        localPin = Port_Ip_PinctrlGetLocalPin(pin);

        if (UINT32_MAX != localPin)
        {
            ret = Port_Ip_ConfigFun(base, pin, localPin, config, value);
        }
    }

    return ret;
}

/** *****************************************************************************************************
 * Syntax             : static uint32 Port_Ip_GetChannelBase(uint32 *channelPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : None
 *
 * Parameters (inout) : channelPtr - pointer to gpio channel
 *
 * Parameters (out)   : None
 *
 * Return value       : gpio channel base address
 *
 * Description        : get gpio channel base
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_005 SW_SM006
 *******************************************************************************************************/
static uint32 Port_Ip_GetChannelBase(uint32 *channelPtr)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint32 baseAddr = UINT32_MAX;
    uint32 gpioIndex;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (NULL_PTR != channelPtr)
    {
        gpioIndex = *channelPtr;
        baseAddr = Port_Ip_GpioGetBase(gpioIndex);
        *channelPtr = Port_Ip_GpioGetIndex(gpioIndex);
    }/* else not needed */

    return baseAddr;
}
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_WriteChannel(uint32 pin, const Port_LevelType level)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - channel id
 *                      level - level value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : write gpio channel level value
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055 SWSR_PORT_056
 *                      SWSR_PORT_005 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_WriteChannel(uint32 pin, const Port_LevelType level)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint32 gpioBaseAddr;
    uint32 bitValue;
    uint32 offset;
    uint32 channel = pin;
    uint8 ret = E_OK;

    gpioBaseAddr = Port_Ip_GetChannelBase(&channel);

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (UINT32_MAX == gpioBaseAddr)
    {
        ret = PORT_E_PARAM_PIN;
    }
    else
    {
        /* #20 channel id Corresponding bit  */
        bitValue = 0x01UL << PORT_PIN_BIT(channel);
        /* #30 channel id Corresponding output level address*/
        offset = PORT_GPIO_OFFSET(PORT_GPIO_DATA_OUT, PORT_PIN_OFFSET(channel));

        if (PORT_PIN_LEVEL_HIGH == level)
        {
            /* #40 set Corresponding bit of PORT_SET_PIN register when level is high*/
            REG_WRITE32(bitValue, (gpioBaseAddr + offset + PORT_SET_PIN));
        }
        else if (PORT_PIN_LEVEL_LOW == level)
        {
            /* #50 set Corresponding bit of PORT_CLEAR_PIN register when level is low*/
            REG_WRITE32(bitValue, (gpioBaseAddr + offset + PORT_CLEAR_PIN));
        }
        else
        {
            ret = PORT_E_CONFIG_PARAM;
        }
    }

    return ret;
}

/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_SetDirection(uint32 pin, const Port_PinDirectionType direction)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - channel id
 *                      direction - direction value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : write gpio channel direction
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055 SWSR_PORT_056
 *                      SWSR_PORT_005 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_SetDirection(uint32 pin, const Port_PinDirectionType direction)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint32 gpioBaseAddr;
    uint32 offset;
    uint32 bitValue;
    uint32 channel = pin;
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if ((PORT_PIN_OUT != direction) && (PORT_PIN_IN != direction))
    {
        ret = PORT_E_CONFIG_PARAM;
    }
    else
    {
        /* #20 channel id Corresponding base address  */
        gpioBaseAddr = Port_Ip_GetChannelBase(&channel);

        if (UINT32_MAX == gpioBaseAddr)
        {
            ret = PORT_E_PARAM_PIN;
        }
        else
        {
            /* #30 channel id Corresponding bit  */
            bitValue = 0x01UL << PORT_PIN_BIT(channel);
            /* #40 channel id Corresponding direction address*/
            offset = PORT_GPIO_OFFSET(PORT_GPIO_OEN, PORT_PIN_OFFSET(channel));

            if (direction == PORT_PIN_OUT)
            {
                /* #50 set Corresponding bit of PORT_SET_PIN register when direction is output*/
                REG_WRITE32(bitValue, gpioBaseAddr + offset + PORT_SET_PIN);
            }
            else
            {
                /* #60 set Corresponding bit of PORT_SET_PIN register when direction is input*/
                REG_WRITE32(bitValue, gpioBaseAddr + offset + PORT_CLEAR_PIN);
            }

            PortHookBegin_Port_Ip_SetDirection();
            PortHookEnd_Port_Ip_SetDirection();
        }
    }

    return ret;
}

#if (PORT_EN_PIN_INT_API == STD_ON)
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_EnableInterruptDetect
 *                                          (uint32 pin, Port_InterruptConfigType interruptType)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - channel id
 *                      interruptType - sync interruptType value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : enable sync interrupt detect
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055 SWSR_PORT_056
 *                      SWSR_PORT_005 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_EnableInterruptDetect(uint32 pin, Port_InterruptConfigType interruptType)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint32 gpioBaseAddr;
    uint32 channelId = pin;
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #20 channel id Corresponding base address  */
    gpioBaseAddr = Port_Ip_GetChannelBase(&channelId);

    if (UINT32_MAX == gpioBaseAddr)
    {
        ret = PORT_E_PARAM_PIN;
    }
    else
    {
        /* #60 Configure low level interrupts*/
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_EN,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_TYPE,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_POL,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_BOTH_EDGE,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));

        switch (interruptType)
        {
        case PORT_PIN_INTERRUPT_LOW_LEVEL:
            /* Configure low level interrupts according to the above three sentences */
            break;

        case PORT_PIN_INTERRUPT_HIGH_LEVEL:
            /* #70 Configure hign level interrupts*/
            REG_WRITE32((PORT_INT_POL_HIGH_POS << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_POL, PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        case PORT_PIN_INTERRUPT_RISING_EDGE:
            /* #80 Configure rising edge interrupts*/
            REG_WRITE32((PORT_INT_TYPE_PULSE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_TYPE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            REG_WRITE32((PORT_INT_POL_HIGH_POS << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_POL, PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        case PORT_PIN_INTERRUPT_FALLING_EDGE:
            /* #90 Configure falling edge interrupts*/
            REG_WRITE32((PORT_INT_TYPE_PULSE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_TYPE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        case PORT_PIN_INTERRUPT_BOTH_EDGE:
            /* #100 Configure both edge interrupts*/
            REG_WRITE32((PORT_INT_TYPE_PULSE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_TYPE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            REG_WRITE32((PORT_INT_BOE_BOTH_EDGE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_BOTH_EDGE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        default:
            ret = PORT_E_CONFIG_PARAM;
            break;
        }

        /* #110 clear interrupt status and enable the interrupt*/
        /*mask interrupt */
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_MASK,
                                     PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));

        /* clear interrupt status */
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_EDGE_CLR,
                                     PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));

        /* unmask interrupt */
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_MASK,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        if (ret == E_OK)
        {
        /* enable interrupt */
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_SINT_EN, PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
        }/* else not needed */
    }

    return ret;

}
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_EnableAsyncInterruptDetect
 *                                          (uint32 channelId, Port_InterruptConfigType interruptType)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : channel - channel id
 *                      interruptType - async interruptType value to write
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : enable async interrupt detect
 * Traceability       : SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055 SWSR_PORT_056
 *                      SWSR_PORT_005 SW_SM006
 *******************************************************************************************************/
static uint8 Port_Ip_EnableAsyncInterruptDetect(uint32 pin, Port_InterruptConfigType interruptType)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint32 gpioBaseAddr;
    uint32 channelId = pin;
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #20 channel id Corresponding base address  */
    gpioBaseAddr = Port_Ip_GetChannelBase(&channelId);

    if (UINT32_MAX == gpioBaseAddr)
    {
        ret = PORT_E_PARAM_PIN;
    }
    else
    {
        /* #60 Configure low level interrupts*/
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_EN,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_TYPE,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_POL,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_BOTH_EDGE,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));

        switch (interruptType)
        {
        case PORT_PIN_ASYC_INTERRUPT_LOW_LEVEL:
            /* Configure low level interrupts according to the above three sentences */
            break;

        case PORT_PIN_ASYC_INTERRUPT_HIGH_LEVEL:
            /* #70 Configure hign level interrupts*/
            REG_WRITE32((PORT_INT_POL_HIGH_POS << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_POL, PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        case PORT_PIN_ASYC_INTERRUPT_RISING_EDGE:
            /* #80 Configure rising edge interrupts*/
            REG_WRITE32((PORT_INT_TYPE_PULSE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_TYPE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            REG_WRITE32((PORT_INT_POL_HIGH_POS << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_POL, PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        case PORT_PIN_ASYC_INTERRUPT_FALLING_EDGE:
            /* #90 Configure falling edge interrupts*/
            REG_WRITE32((PORT_INT_TYPE_PULSE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_TYPE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        case PORT_PIN_ASYC_INTERRUPT_BOTH_EDGE:
            /* #100 Configure both edge interrupts*/
            REG_WRITE32((PORT_INT_TYPE_PULSE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_TYPE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            REG_WRITE32((PORT_INT_BOE_BOTH_EDGE << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_BOTH_EDGE,
                                         PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
            break;

        default:
            ret = PORT_E_CONFIG_PARAM;
            break;
        }

        /* #110 clear interrupt status and enable the interrupt*/
        /*mask interrupt */
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_MASK,
                                     PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));

        /* clear interrupt status */
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_EDGE_CLR,
                                     PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));

        /* unmask interrupt */
        REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                    (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_MASK,
                                     PORT_PIN_OFFSET(channelId)) + PORT_CLEAR_PIN)));
        if (ret == E_OK)
        {
            /* enable interrupt */
            REG_WRITE32((0x1UL << PORT_PIN_BIT(channelId)),
                        (gpioBaseAddr + (PORT_GPIO_OFFSET(PORT_GPIO_AINT_EN, PORT_PIN_OFFSET(channelId)) + PORT_SET_PIN)));
        }/* else not needed */
    }

    return ret;

}
#endif /** #if (PORT_EN_PIN_INT_API == STD_ON)*/
/** *****************************************************************************************************
 * Syntax             : static Std_ReturnType Port_Ip_DioConfig(const Port_SettingsConfigType *configPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : configPtr - pointer to PINCTRL configuration parameters
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : Dio pin config, for MUX0 only
 * Traceability       : SWSR_PORT_005 SWSR_PORT_007 SWSR_PORT_009 SWSR_PORT_017
 *                      SWSR_PORT_018 SWSR_PORT_040 SWSR_PORT_055 SWSR_PORT_056
 *                      SW_SM006
 *******************************************************************************************************/
static Std_ReturnType Port_Ip_DioConfig(const Port_SettingsConfigType *configPtr)
{
    /* ----- Local Variables ---------------------------------------------- */
    Std_ReturnType ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (NULL_PTR == configPtr)
    {
        ret =  PORT_E_PARAM_POINTER;
    }
    else
    {
        /* #20 set initial level value, for output direction only */
        if (PORT_PIN_OUT == configPtr->dataDirection)
        {
            ret = Port_Ip_WriteChannel(configPtr->pinIndex, configPtr->initialValue);
        }/* else not needed */

        /* #30 set direction */
        CALL_RET_CHECK(ret, Port_Ip_SetDirection(configPtr->pinIndex, configPtr->dataDirection));

#if (PORT_EN_PIN_INT_API == STD_ON)

        /* #40 set interrupt, for input direction only */
        if ((PORT_PIN_IN == configPtr->dataDirection))
        {
            if ( PORT_PIN_INTERRUPT_DISABLED != configPtr->interruptConfig)
            {
                if (configPtr->interruptConfig <= PORT_PIN_INTERRUPT_BOTH_EDGE)
                {
                    /* #50 set sync interrupt */
                    CALL_RET_CHECK(ret, Port_Ip_EnableInterruptDetect(configPtr->pinIndex, configPtr->interruptConfig));
                }
                else
                {
                    /* #40 set async interrupt */
                    CALL_RET_CHECK(ret, Port_Ip_EnableAsyncInterruptDetect(configPtr->pinIndex,
                                   (configPtr->interruptConfig)));
                }
            }/* else not needed */
        }/* else not needed */

#endif /** #if (PORT_EN_PIN_INT_API == STD_ON)*/
    }

    return ret;
}
#if ((PORT_SET_PIN_DIRECTION_API == STD_ON) || (STD_ON == PORT_SET_PIN_MODE_API))
/** *****************************************************************************************************
 * Syntax             : static uint8 Port_Ip_IndexInConfig(Port_PinType pin,
 *                              const Port_SettingsConfigType* configPtr, uint8 configNum, uint8* indexPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - the pin whose index to find.
 *                      configPtr - pointer to PINCTRL configuration parameters, find pin in init configuration.
 *                      configNum - init configuration settings number.
 *
 * Parameters (inout) : pIndex - pointer to pin index.
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : find pin index in the init configuration.
 * Traceability       : SWSR_PORT_08 SWSR_PORT_010 SWSR_PORT_051
 *******************************************************************************************************/
static uint8 Port_Ip_IndexInConfig(Port_PinType pin, const Port_SettingsConfigType *configPtr,
                                   uint16 configNum, uint16 *indexPtr)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint16 index = 0U;
    uint8 ret = E_OK;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 find pin index in the init configuration */
    while (index < configNum)
    {

        if (configPtr[index].pinIndex == pin)
        {
            *indexPtr = index;
            break;
        }/* else not needed */

        index++;
    }

    /* #10 can not find the index in init configuration */
    if (index == configNum)
    {
        ret = PORT_E_PARAM_PIN;
    }/* else not needed */

    return ret;
}
#endif /**#if ((PORT_SET_PIN_DIRECTION_API == STD_ON) || (STD_ON == PORT_SET_PIN_MODE_API))*/

/*PRQA S 2755 30*/
/** *****************************************************************************************************
 * \brief This function is internal interface for port init.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_Init(const Port_SettingsConfigType* settingsPtr, uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : settingsPtr - Pointer to the init configuration settings
 *                      num - init configuration settings number
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for port init.
 * \endverbatim
 * Traceability       : SWSR_PORT_003 SWSR_PORT_004 SWSR_PORT_005 SWSR_PORT_006
 *                      SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055 SWSR_PORT_056
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_Init(const Port_SettingsConfigType *settingsPtr, uint16 num)
{
    /* ----- Local Variables ---------------------------------------------- */
    Std_ReturnType ret = E_OK;
    uint32 i;
    const Port_SettingsConfigType *configPtr;
    uint32 base;
    boolean isAnalogPin;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (NULL_PTR == settingsPtr)
    {
        ret = PORT_E_PARAM_POINTER;
    }
    else
    {
        for (i = 0; i < num; i++)
        {
            configPtr = &settingsPtr[i];

            if (configPtr->pinIndex >= PORT_PIN_NUM)
            {
                ret = PORT_E_PARAM_PIN;
            }
            else
            {
                base = Port_Ip_PinctrlGetBase(configPtr->pinIndex);
                /* #20 set pin mux */
                ret = Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_FUNCTION, (uint32)configPtr->mux);
                /* #30 set opendrain/push pull */
                CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_DRIVE,
                                                   (uint32)configPtr->openDrain));
                /* #40 set pulls mode */
                CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_PULL,
                                                   (uint32)configPtr->pullConfig));
                /* #50 set drive strength */
                CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_DRIVE_STRENGTH,
                                                   (uint32)configPtr->driveStrength));
                /* #60 set slew rate */
                CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_SLEW_RATE,
                                                   (uint32)configPtr->slewRate));
                /* #70 set schmitt mode */
                CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_INPUT_SCHMITT,
                                                   (uint32)configPtr->inputSelect));
                /* #80 set force input */
                CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_FORCE_INPUT,
                                                   (uint32)configPtr->forceInput));
                /* #90 set force Output */
                CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_FORCE_OUTPUT,
                                                   (uint32)configPtr->forceOutput));

                /* #100 set MS when GPIO A/B/C used as digital*/
                isAnalogPin = Port_Ip_IsAnalogPin(configPtr->pinIndex);

                if (TRUE == isAnalogPin)
                {
                    CALL_RET_CHECK(ret, Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_MODE_SELECT, 0U));
                }/* else not needed */

                /* #110 set dio config, include level/direction and interrupt*/
                if (configPtr->mux == PORT_PIN_MUX_ALT0)
                {
                    CALL_RET_CHECK(ret, Port_Ip_DioConfig(configPtr));
                }/* else not needed */
            }

            /* #120 any error will break the for cycle*/
            if (E_OK != ret)
            {
                break;
            }/* else not needed */
        }
    }

    return ret;
}
#if (PORT_ANALOG_PIN_ENABLE == STD_ON)
/** *****************************************************************************************************
 * \brief This function is internal interface for analog port init.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_AnalogPadInit
 *                                      (const Port_AnalogConfigType* settingsPtr, const uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : settingsPtr - Pointer to the init analog configuration settings
 *                      num - init analog configuration settings number
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for analog port init.
 *                      This function is available if the PORT_ANALOG_PIN_ENABLE is set STD_ON
 * \endverbatim
 * Traceability       : SWSR_PORT_003 SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055
 *                      SWSR_PORT_056 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_AnalogPadInit(const Port_AnalogConfigType *settingsPtr, const uint16 num)
{
    /* ----- Local Variables ---------------------------------------------- */
    Std_ReturnType ret;
    uint32 i;
    const Port_AnalogConfigType *configPtr;
    uint32 base;
    boolean flag = FALSE;
    boolean isAnalogPin;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (NULL_PTR == settingsPtr)
    {
        ret = PORT_E_PARAM_POINTER;
    }
    else if (0U == num)
    {
        ret = PORT_E_INIT_FAILED;
    }
    else
    {
        for (i = 0U; i < num; i++)
        {
            configPtr = &settingsPtr[i];

            if (configPtr->pinIndex >= PORT_PIN_NUM)
            {
                ret = PORT_E_PARAM_PIN;
                flag = TRUE;
            }
            else
            {
                base = Port_Ip_PinctrlGetBase(configPtr->pinIndex);
                /* check for analog pin*/
                isAnalogPin = Port_Ip_IsAnalogPin(configPtr->pinIndex);

                if (FALSE == isAnalogPin)
                {
                    ret = PORT_E_CONFIG_PARAM;
                    flag = TRUE;
                }
                else
                {
                    /* #20 set analog pin mode select*/
                    /* analog input 3v3 or 5v */
                    ret = Port_Ip_Config(base, configPtr->pinIndex, PORT_CONFIG_MODE_SELECT,
                                         (uint32)configPtr->inputLevel);

                    if (E_OK != ret)
                    {
                        /* #40 any error will break the for cycle*/
                        flag = TRUE;
                    }
                }
            }

            if (TRUE == flag)
            {
                break;
            }
        }
    }

    return ret;
}
#endif /** #if (PORT_ANALOG_PIN_ENABLE == STD_ON)*/

#if (PORT_SET_PIN_DIRECTION_API == STD_ON)
/** *****************************************************************************************************
 * \brief This function is internal interface for set direction of Dio pads at runtime.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_SetPinDirection
 *                        (Port_PinType pin, Port_PinDirectionType direction,
 *                         const Port_SettingsConfigType* cfgPtr, uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - the pin which direction to be set
 *                      direction - the direction to be set, 0 for input and 1 for output.
 *                      cfgPtr - the pointer to the init configuration, used to check pin direction changable
 *                      num - the number of the init configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for set direction of Dio pads at runtime.
 *                      Only gpio pins which pin direct changable can be modifed.
 *                      This function is available if the PORT_SET_PIN_DIRECTION_API is set STD_ON
 * \endverbatim
 * Traceability       : SWSR_PORT_005 SWSR_PORT_008 SWSR_PORT_017 SWSR_PORT_018
 *                      SWSR_PORT_055 SWSR_PORT_056 SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_SetPinDirection(Port_PinType pin, Port_PinDirectionType direction,
                                       const Port_SettingsConfigType *cfgPtr, uint16 num)
{
    /* ----- Local Variables ---------------------------------------------- */
    Std_ReturnType ret;
    uint16 index = 0;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (NULL_PTR == cfgPtr)
    {
        ret = PORT_E_PARAM_POINTER;
    }
    else
    {
        /* #20 find pin index in the init configuration */
        ret = Port_Ip_IndexInConfig(pin, cfgPtr, num, &index);

        if (E_OK == ret)
        {
            /* #30 check pin directChangable */
            if (FALSE == cfgPtr[index].directChangable)
            {
                ret = PORT_E_DIRECTION_UNCHANGEABLE;
            }
            else
            {
                /* #40 modify pin direction */
                ret = Port_Ip_SetDirection(pin, direction);
            }
        }/* else not needed */
    }

    return ret;
}
#endif /** #if (PORT_SET_PIN_DIRECTION_API == STD_ON)*/
/** *****************************************************************************************************
 * \brief This function is internal interface for refresh the pin direction of Dio pads at runtime.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_RefreshPortDirection
 *                                          (const Port_SettingsConfigType* cfgPtr, uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : cfgPtr - the pointer to the init configuration, used to check pin direction changable
 *                      num - the number of the init configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for refresh the pin direction of Dio pads at runtime.
 *                      Only gpio pins which pin direct not changable can be refreshed.
 * \endverbatim
 * Traceability       : SWSR_PORT_005  SWSR_PORT_010 SWSR_PORT_017 SWSR_PORT_018
 *                      SWSR_PORT_046  SWSR_PORT_047 SWSR_PORT_055 SWSR_PORT_056
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_RefreshPortDirection(const Port_SettingsConfigType *cfgPtr, uint16 num)
{
    /* ----- Local Variables ---------------------------------------------- */
    Std_ReturnType ret = E_OK;
    uint32 i;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (NULL_PTR == cfgPtr)
    {
        ret = PORT_E_PARAM_POINTER;
    }
    else
    {
        for (i = 0U; i < num; i++)
        {

            /* #30 check pin directChangable, for gpio setting and pin direct not changable only*/
            if ((PORT_PIN_MUX_ALT0 == cfgPtr[i].mux) && (FALSE == cfgPtr[i].directChangable))
            {
                /* #40 refresh pin direction*/
                ret = Port_Ip_SetDirection(cfgPtr[i].pinIndex, cfgPtr[i].dataDirection);

                if (E_OK != ret)
                {
                    /* #50 any error will break the for cycle*/
                    break;
                }/* else not needed */

            } /* else not needed */
        }
    }

    return ret;
}

#if (STD_ON == PORT_SET_PIN_MODE_API)
/** *****************************************************************************************************
 * \brief This function is internal interface for set pin mode at runtime.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_SetPinMode(Port_PinType pin, Port_PinModeType mode,
 *                                                      const Port_SettingsConfigType* cfgPtr, uint16 num);
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - the pin which mode to be set
 *                      mode - the mode to be set, PORT_PIN_MUX_ALT0~PORT_PIN_MUX_ALT9
 *                      cfgPtr - the pointer to the init configuration, used to check pin mode changable
 *                      num - the number of the init configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for set pin mode at runtime.
 *                      Only pin which mode changable can be modifed.
 *                      This function is available if the PORT_SET_PIN_MODE_API is set STD_ON
 * \endverbatim
 * Traceability       : SWSR_PORT_005 SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_051
 *                      SWSR_PORT_052 SWSR_PORT_053 SWSR_PORT_055 SWSR_PORT_056
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_SetPinMode(Port_PinType pin, Port_PinModeType mode,
                                  const Port_SettingsConfigType *cfgPtr, uint16 num)
{
    /* ----- Local Variables ---------------------------------------------- */
    Std_ReturnType ret;
    uint16 index = 0;
    uint32 base;

    /* ----- Implementation ----------------------------------------------- */
    /* #10 Check input parameters for plausibility */
    if (NULL_PTR == cfgPtr)
    {
        ret = PORT_E_PARAM_POINTER;
    }
    else if (pin >= PORT_PIN_NUM)
    {
        ret = PORT_E_PARAM_PIN;
    }
    else
    {
        base = Port_Ip_PinctrlGetBase(pin);

        /* #20 find pin index in the init configuration */
        ret = Port_Ip_IndexInConfig(pin, cfgPtr, num, &index);

        if (E_OK == ret)
        {
            /* #30 check mode directChangable */
            if (FALSE == cfgPtr[index].modeChangable)
            {
                ret = PORT_E_MODE_UNCHANGEABLE;
            }
            else
            {
                /* #40 check mux range */
                if ((mode > PORT_PIN_MUX_ALT9))
                {
                    ret = PORT_E_PARAM_INVALID_MODE;
                }
                else
                {
                    /* #50 modify pin mux */
                    ret = Port_Ip_Config(base, pin, PORT_CONFIG_FUNCTION, (uint32)mode);
                }
            }
        }/* else not needed */
    }

    return ret;
}
#endif /** #if (STD_ON == PORT_SET_PIN_MODE_API)*/

#define PORT_STOP_SEC_CODE
#include "Port_MemMap.h"

#ifdef __cplusplus
}
#endif

/* End of file */
